/**
 * @p.md
 * 
 * Dispatcher 模块，负责调度 Actor 的消息处理
 */

/**
 * 调度器接口，定义了消息处理的调度策略
 */
export interface Dispatcher {
  /**
   * 调度任务执行
   * @param fn 要执行的函数
   */
  schedule(fn: () => void): void;
  
  /**
   * 获取消息处理吞吐量
   * @returns 每次调度周期中处理的最大消息数
   */
  throughput(): number;
}

/**
 * 同步调度器，立即在当前线程执行消息处理
 */
export class SynchronousDispatcher implements Dispatcher {
  private readonly _throughput: number;
  
  /**
   * 构造同步调度器
   * @param throughput 每次调度周期中处理的最大消息数，默认为 300
   */
  constructor(throughput: number = 300) {
    this._throughput = throughput;
  }
  
  /**
   * 立即执行给定的函数
   * @param fn 要执行的函数
   */
  schedule(fn: () => void): void {
    fn();
  }
  
  /**
   * 获取吞吐量限制
   */
  throughput(): number {
    return this._throughput;
  }
}

/**
 * 任务队列调度器，将任务放入队列依次执行
 */
export class TaskQueueDispatcher implements Dispatcher {
  private readonly _throughput: number;
  private _tasks: (() => void)[] = [];
  private _executing: boolean = false;
  
  /**
   * 构造任务队列调度器
   * @param throughput 每次调度周期中处理的最大消息数，默认为 300
   */
  constructor(throughput: number = 300) {
    this._throughput = throughput;
  }
  
  /**
   * 将任务添加到队列
   * @param fn 要执行的函数
   */
  schedule(fn: () => void): void {
    this._tasks.push(fn);
    this.executeTasks();
  }
  
  /**
   * 执行队列中的任务
   */
  private executeTasks(): void {
    if (this._executing) {
      return;
    }
    
    this._executing = true;
    
    setTimeout(() => {
      while (this._tasks.length > 0) {
        const task = this._tasks.shift();
        if (task) {
          try {
            task();
          } catch (error) {
            console.error('Error executing task:', error);
          }
        }
      }
      
      this._executing = false;
    }, 0);
  }
  
  /**
   * 获取吞吐量限制
   */
  throughput(): number {
    return this._throughput;
  }
}

/**
 * 线程池调度器（模拟），使用 setTimeout 将任务放入事件循环
 */
export class ThreadPoolDispatcher implements Dispatcher {
  private readonly _throughput: number;
  
  /**
   * 构造线程池调度器
   * @param throughput 每次调度周期中处理的最大消息数，默认为 300
   */
  constructor(throughput: number = 300) {
    this._throughput = throughput;
  }
  
  /**
   * 将任务放入事件循环
   * @param fn 要执行的函数
   */
  schedule(fn: () => void): void {
    setTimeout(fn, 0);
  }
  
  /**
   * 获取吞吐量限制
   */
  throughput(): number {
    return this._throughput;
  }
}

/**
 * 调度器工厂，提供创建不同类型调度器的方法
 */
export const Dispatchers = {
  /**
   * 创建同步调度器
   * @param throughput 每次调度周期中处理的最大消息数
   * @returns 同步调度器实例
   */
  synchronous(throughput?: number): Dispatcher {
    return new SynchronousDispatcher(throughput);
  },
  
  /**
   * 创建任务队列调度器
   * @param throughput 每次调度周期中处理的最大消息数
   * @returns 任务队列调度器实例
   */
  taskQueue(throughput?: number): Dispatcher {
    return new TaskQueueDispatcher(throughput);
  },
  
  /**
   * 创建线程池调度器
   * @param throughput 每次调度周期中处理的最大消息数
   * @returns 线程池调度器实例
   */
  threadPool(throughput?: number): Dispatcher {
    return new ThreadPoolDispatcher(throughput);
  }
}; 